package mspbots.cw.business.core.configurations;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.cw.business.core.BaseReceiver;
import mspbots.cw.common.RabbitKeys;
import mspbots.cw.common.ResultMsg;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.time.Duration;
import java.util.Iterator;

/**
 * @author Jay.Yang
 */
@Log4j2
@Component
@RequiredArgsConstructor
public class ConfigurationsReceiver extends BaseReceiver {

    private final ConfigurationsRepository configurationsRepository;
    private final ConfigurationsQuestionsRepository questionsRepository;

    @RabbitListener(queues = "connect-wise.configurations.tl")
    public void process(ResultMsg resultMsg) {
        try {
            JsonNode entity = resultMsg.getEntity();
            Configurations data = super.objectMapper.convertValue(entity, Configurations.class);
            data.setId(null);
            data.setCwId(resultMsg.getId());
            data.setTenantCode(resultMsg.getTenantId());
            data.setSyncTime(resultMsg.getSyncDate());
            data.setUpdatedBy(super.getStringValue(entity.findValue("updatedBy")));
            data.setLastUpdated(super.getDateTimeValue(entity.findValue("lastUpdated")));

            data.setTypeName(super.getStringValueName(entity.get("type")));
            data.setStatusName(super.getStringValueName(entity.get("status")));
            data.setCompanyName(super.getStringValueName(entity.get("company")));
            data.setCompanyId(super.getLongValueId(entity.get("company")));
            data.setCompanyIdentifier(super.getStringValueIdentifier(entity.get("company")));
            data.setContactName(super.getStringValueName(entity.get("contact")));
            data.setManufacturerName(super.getStringValueName(entity.get("manufacturer")));
            data.setInstalledByIdentifier(super.getStringValueIdentifier(entity.get("installedBy")));

            this.configurationsRepository.findByCwIdAndTenantCode(resultMsg.getId(), resultMsg.getTenantId())
                    .map(result -> {
                        data.setId(result.getId());
                        return data;
                    })
                    .defaultIfEmpty(data)
                    .flatMap(this.configurationsRepository::save).block(Duration.ofSeconds(10));

            processQuestions(resultMsg);

        } catch (Exception e) {
            messagingTemplate.convertAndSend(RabbitKeys.BASE_EXCHANGE_NAME, RabbitKeys.BAD_MESSAGE_QUEUE_KEY, resultMsg);
        }
    }

    private void processQuestions(ResultMsg resultMsg) {
        JsonNode questionsNode = resultMsg.getEntity().get("questions");
        if (ObjectUtils.isEmpty(questionsNode) || questionsNode.isEmpty()) {
            return;
        }
        Iterator<JsonNode> elements = questionsNode.elements();
        while (elements.hasNext()) {
            JsonNode next = elements.next();
            try {
                ConfigurationsQuestions data = super.objectMapper.convertValue(next, ConfigurationsQuestions.class);
                data.setConfigurationId(resultMsg.getId());
                data.setTenantCode(resultMsg.getTenantId());
                data.setSyncTime(resultMsg.getSyncDate());
                this.questionsRepository.findByAnswerIdAndConfigurationIdAndTenantCode(data.getAnswerId(),
                        resultMsg.getId(), resultMsg.getTenantId())
                        .map(result -> {
                            data.setId(result.getId());
                            return data;
                        })
                        .defaultIfEmpty(data)
                        .flatMap(this.questionsRepository::save).block(Duration.ofSeconds(10));
            } catch (IllegalArgumentException e) {
                log.error("------------ConfigurationsQuestions parse error!!!---------data:{}", next);
                log.error(e.getMessage());
            }
        }
    }
}
